package com.example.springbatch6_context;

import com.example.job_listener.JobAnnStateListener;
import com.example.job_listener.JobStateListener;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.listener.JobListenerFactoryBean;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import javax.annotation.Resource;

/***
 *
 */
@SpringBootApplication
@EnableBatchProcessing //启用springbatch框架 需要的注解
public class SpringBatchApplication6 {

    // job调度器
    @Autowired
    private JobLauncher jobLauncher;

    // job构建工厂
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    // step步骤构建工厂
    @Autowired
    private StepBuilderFactory stepBuilderFactory;


    @Bean
    public Tasklet tasklet1() {
        return (stepContribution, chunkContext) -> {

            // 获取job/step 的 ExecutionContext
            ExecutionContext stepExecutionContext = chunkContext.getStepContext().getStepExecution().getExecutionContext();
            ExecutionContext jobExecutionContext = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();

            // stepExecutionContext 只是在同一个step生效
            stepExecutionContext.putString("stepExContextKey","stepExContextVal");

            // jobExecutionContext 在同于一个job内的多哥step都生效
            jobExecutionContext.putString("jobExContextKey","jobExContextVal");


            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }


    @Bean
    public Tasklet tasklet2() {
        return (stepContribution, chunkContext) -> {

            // 获取job/step 的 ExecutionContext
            ExecutionContext executionContext = chunkContext.getStepContext().getStepExecution().getExecutionContext();
            ExecutionContext executionContext1 = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();

            // 获取context中的变量
            String stepExContextVal = (String) executionContext.get("stepExContextKey");
            String jobExContextVal = (String) executionContext1.get("jobExContextKey");

            System.err.println("stepExContextVal = " + stepExContextVal);  // not null
            System.err.println("jobExContextVal = " + jobExContextVal);    // null


            // 返回执行任务完成
            return RepeatStatus.FINISHED;
        };
    }

    // 作业步骤 不带不读写操作
    @Bean
    public Step step1() {
        // 如果是通过延时加载去获取参数 那么这里的入参就置为null
        return stepBuilderFactory.get("step1").tasklet(tasklet1()).build();
    }

    @Bean
    public Step step2() {
        // 如果是通过延时加载去获取参数 那么这里的入参就置为null
        return stepBuilderFactory.get("step2").tasklet(tasklet2()).build();
    }



    @Bean
    public Job job() {
        return jobBuilderFactory
                .get("job-context-01")
                .incrementer(new RunIdIncrementer())    // 使用增量器(run.id自增)
//                .incrementer(jobParametersIncrementer)    // 使用日期增量器
                .start(step1())
                .next(step2())
//                .listener(jobStateListener)          //添加监听器
//                .listener(jobAnnStateListener)          //添加监听器
                .listener(JobListenerFactoryBean.getListener(new JobAnnStateListener()))     //通过JobListenerFactoryBean 获取，添加监听器

                .build();
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringBatchApplication6.class, args);
    }

}
